import pygame
import sys
from animation import *
from character import *
from util import *
import content

pygame.display.init()

width = 384
height = 288
zoom = 2

_screen = pygame.display.set_mode((width * zoom, height * zoom))
screen = pygame.surface.Surface((width, height))


content.loadContent()

clock = pygame.time.Clock()
pygame.font.init()
font = pygame.font.SysFont("Courier New", 16)

charName = sys.argv[1]
char = allCharacters[charName](content.images[charName]["imagelist"])
charAnimNames,charAnims = zip(*list(char.animations.items()))
charAnimIndex = 0
char.anim = charAnims[charAnimIndex]
loadBoxData(charName, char)

paused = True
advance = 0
boxmode = 0
frameNum = 0
lastBox = None
lastBoxType = 0
boxStart = None
clipboard = None
drawHitboxes = True
loopmode = False
textboxPrompt = ""
activeTextbox = None
textboxEntry = ""

def hitTest(pt):
	(x,y) = pt
	for b in char.getAbsBoxFrame():
		r = b.rect
		if r[2] < 0:
			r[0] -= r[2]
			r[2] = -r[2]
		if r[3] < 0:
			r[1] -= r[3]
			r[3] = -r[3]
		if x >= r[0] and x < r[0] + r[2] and y >= r[1] and y < r[1] + r[3]:
			return b
	return None

selectedBox = None

def onEnterPropertyName(propname):
	global textboxPrompt, activeTextbox, selectedBox, textboxOnEnter
	if propname in selectedBox.properties:
		textboxPrompt = "New value (old = '" + selectedBox.properties[propname] + "'): "
	else:
		textboxPrompt = "New value (no previous value):"
	activeTextbox = ""
	textboxOnEnter = lambda x:onEnterPropertyValue(propname, x)

def onEnterPropertyValue(propname, propvalue):
	global textboxPrompt, activeTextbox, selectedBox, textboxOnEnter
	if propvalue != "":
		selectedBox.properties[propname] = propvalue
	activeTextbox = None
	selectedBox = None
	textboxPrompt = None
	textboxOnEnter = None

while 1:
	clock.tick(60)
	events = pygame.event.get()

	if activeTextbox is not None:
		screen.fill((100, 100, 100))
	elif not paused:
		screen.fill((255,255,255))
	else:
		screen.fill((200, 220, 255))


	char.render(screen, (0,0))
	if paused or drawHitboxes:
		char.renderHitbox(screen, (0,0))
		pygame.draw.rect(screen, (0,255,255), (char.x - 1, char.y - 1, 3, 3))

	if paused:
		(mx, my) = pygame.mouse.get_pos()
		mx /= zoom
		my /= zoom

		blink = 100 * (frameNum % 2)
		if boxmode == 0:
			boxmodeColor = (blink, blink, 255)
		elif boxmode == 1:
			boxmodeColor = (255, blink, blink)
		else:
			boxmodeColor = (255, 255, 255)
		pygame.draw.line(screen, boxmodeColor, (mx - 5, my), (mx + 5, my))
		pygame.draw.line(screen, boxmodeColor, (mx, my - 5), (mx, my + 5))

		if boxStart:
			pygame.draw.rect(screen, boxmodeColor, (boxStart[0], boxStart[1], mx - boxStart[0], my - boxStart[1]), 1)
		if lastBox:
			pygame.draw.rect(screen, boxmodeColor, lastBox, 1)


	else:
		lastBox = None
		boxStart = None

	txt = "Animation " + str(charAnimIndex) + ": "+charAnimNames[charAnimIndex]+" (" + str(char.anim.n + 1) + "/"+str(len(char.anim.frames)) + ")"
	info = font.render(txt, False, (0, 0, 0))
	screen.blit(info, (10, 7))

	if(activeTextbox is not None):
		txt = textboxPrompt + activeTextbox
		textbox = font.render(txt, False, (0, 0, 0))
		pygame.draw.rect(screen, (255, 255, 255), (10, 24, textbox.get_width(), textbox.get_height()), 0)
		screen.blit(textbox, (10, 24))

	pygame.transform.scale(screen, (width * zoom, height * zoom), _screen)

	pygame.display.update()

	if not paused or advance > 0:
		if frameNum % 4 == 0:
			if loopmode:
				char.anim.n = (char.anim.n + 1) % len(char.anim.frames)
			else:
				char.anim.n = min(char.anim.n + 1, len(char.anim.frames)-1)
		frameNum += 1
		advance -= 1

	for evt in events:
		if evt.type == pygame.QUIT:
			sys.exit()

		if evt.type == pygame.KEYDOWN:
			if activeTextbox is not None:
				if (evt.key >= pygame.K_0 and evt.key <= pygame.K_9) or (evt.key >= pygame.K_a and evt.key <= pygame.K_z):
					activeTextbox += str(pygame.key.name(evt.key))
				if evt.key == pygame.K_BACKSPACE:
					activeTextbox = activeTextbox[:-1]
				if evt.key == pygame.K_RETURN:
					textboxOnEnter(activeTextbox)
			else:
				if evt.key == pygame.K_SPACE:
					paused = not paused
				if evt.key == pygame.K_UP:
					charAnimIndex = (charAnimIndex - 1) % len(charAnims)
					char.anim = charAnims[charAnimIndex]
					char.anim.start()
				if evt.key == pygame.K_DOWN:
					charAnimIndex = (charAnimIndex + 1) % len(charAnims)
					char.anim = charAnims[charAnimIndex]
					char.anim.start()
				elif evt.key == pygame.K_LEFT:
					char.anim.n = (char.anim.n - 1) % len(char.anim.frames);
				elif evt.key == pygame.K_RIGHT:
					char.anim.n = (char.anim.n + 1) % len(char.anim.frames);
				elif evt.key == pygame.K_l:
					loopmode = not loopmode
				elif evt.key == pygame.K_1:
					boxmode = 0
				elif evt.key == pygame.K_2:
					boxmode = 1
				elif evt.key == pygame.K_3:
					boxmode = 2
				elif evt.key == pygame.K_SLASH:
					drawHitboxes = not drawHitboxes
				elif evt.key == pygame.K_ESCAPE:
					boxStart = None
					try:
						char.anim.getHitboxFrame().pop()
					except(IndexError):
						pass
				elif evt.key == pygame.K_c:
					clipboard = [f for f in char.anim.getHitboxFrame()]
				elif evt.key == pygame.K_v:
					char.anim.hitboxFrames[char.anim.n] = [f for f in clipboard]
				elif evt.key == pygame.K_s:
					saveBoxData(charName, char)


		if evt.type == pygame.MOUSEBUTTONDOWN and paused:
			if evt.button == 1:
				if boxmode == 2:
					selectedBox = hitTest((evt.pos[0] / zoom, evt.pos[1] / zoom))
					if selectedBox is not None:
						textboxPrompt = "Property name: "
						activeTextbox = ""
						textboxOnEnter = onEnterPropertyName

				else:
					boxStart = (evt.pos[0]/zoom, evt.pos[1]/zoom)


		if evt.type == pygame.MOUSEBUTTONUP and paused:
			if evt.button == 1 and boxStart != None:
				lastBox = (boxStart[0], boxStart[1], evt.pos[0] / zoom - boxStart[0], evt.pos[1] / zoom - boxStart[1])
				if lastBox:
					box = Hitbox((lastBox[0] - char.x, lastBox[1] - char.y, lastBox[2], lastBox[3]), {"type" : boxmode})
					if boxmode == 1:
						textboxPrompt = "damage: "
						activeTextbox = ""
						selectedBox = box
						textboxOnEnter = lambda x:onEnterPropertyValue("damage", x)

					char.anim.getHitboxFrame().append(box)
					lastBox = None

				boxStart = None
